:- use_module(library(clpfd)).

tipo_operacao(final).
tipo_operacao(daytrade).

corretora(fator).
corretora(agora).
corretora(easyinvest).
corretora(itau).
corretora(bb).

%emolumentos
%========================================================
emolumentos(Valor,tipo_operacao(O),X) :-
  O = final,
  X #= (Valor * 35)/100000.
emolumentos(Valor,tipo_operacao(O),X) :-
  O = daytrade,
  X #= (Valor * 25)/100000.
%=========================================================

%corretagem
%=========================================================
corretagem(corretora(C),Valor,X,tipo_operacao(O)) :-
  C = agora,
  corretagem(corretora(C),Valor,X).
corretagem(corretora(C),Valor,X) :-
  C = agora,
  X #= (10525 * 20)/100.

corretagem(corretora(C),Valor,X,tipo_operacao(O)) :-
	C = easyinvest,
	corretagem(corretora(C),Valor,X).
corretagem(corretora(C),Valor,X) :-
  C = easyinvest,
  X #= (10525 * 10)/100.

corretagem(corretora(C),Valor,X,tipo_operacao(O)) :-
  C = fator,
  corretagem(corretora(C),Valor,X).
corretagem(corretora(C),Valor,X) :-
  C = fator,
  Valor in 0..13505,
  Taxa is 0,
  Fixo is 270,
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = fator,
  Valor in 13506..49861,
  Taxa is 20,
  Fixo is 0,
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = fator,
  Valor in 49862..151468,
  Taxa is 15,
  Fixo is 249,	
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = fator,
  Valor in 151469..302637,
  Taxa is 10,
  Fixo is 1006,
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = fator,
  Valor in 302638..1000000000,
  Taxa is 5,
  Fixo is 2521,
  X #= (Taxa * Valor)/1000 + Fixo.

corretagem(corretora(C),Valor,X,tipo_operacao(O)) :-
  C = itau,
  O = daytrade,
  corretagem(corretora(C),Valor,Y),
  X#=Y/2.
corretagem(corretora(C),Valor,X) :-
  C = itau,
  Valor in 0..13507,
  Taxa is 0,
  Fixo is 270,
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = itau,
  Valor in 13508..49862,
  Taxa is 20,
  Fixo is 0,
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = itau,
  Valor in 49863..151469,
  Taxa is 15,
  Fixo is 249,	
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = itau,
  Valor in 151470..302938,
  Taxa is 10,
  Fixo is 1006,
  X #= (Taxa * Valor)/1000 + Fixo.
corretagem(corretora(C),Valor,X) :-
  C = itau,
  Valor in 302939..1000000000,
  Taxa is 5,
  Fixo is 2521,
  X #= (Taxa * Valor)/1000 + Fixo.

corretagem(corretora(C),Valor,X) :-
  C = bb,
  X #= 2000.
%===========================================================
%

%Custos
%%==========================================================
custo(tipo_operacao(O),Valor,corretora(C),Custo) :-
  corretagem(corretora(C),Valor,Y),
  emolumentos(Valor,tipo_operacao(O),Z),
  Custo #= Y + Z.
custo(tipo_operacao(O),Preco,Quantidade,corretora(C),Custo) :-
  Valor #= Preco*Quantidade,
  custo(tipo_operacao(O),Valor,corretora(C),Custo).
custo(tipo_operacao(O),corretora(C),Preco,Quantidade,Custo) :-
  Valor #= Preco*Quantidade,
  custo(tipo_operacao(O),Valor,corretora(C),Custo).

%===========================================================

balanco(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,QuantidadeComprada,QuantidadeVendida,Balanco) :-
  Vars = [PrecoCompra,PrecoVenda,QuantidadeComprada,QuantidadeVendida,Balanco,A,B,CC,CV],
  PrecoCompra #> 0,
  PrecoVenda #> 0,
  QuantidadeComprada #> 0,
  QuantidadeVendida #=< QuantidadeComprada,
  A in 0..1000000000000,
  B in 0..1000000000000,
  A #= QuantidadeComprada * PrecoCompra,
  B #= QuantidadeVendida * PrecoVenda,
  custo(tipo_operacao(O),A,corretora(C),CC),
  custo(tipo_operacao(O),B,corretora(C),CV),
  B - A - CC - CV #= Balanco.

balanco(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,Quantidade,Balanco) :-
  balanco(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,Quantidade,Quantidade,Balanco).

lucro(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,QuantidadeComprada,QuantidadeVendida,Lucro) :-
  Lucro #>= 0,
  balanco(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,QuantidadeComprada,QuantidadeVendida,Lucro),!.
      
menorLucro(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,QuantidadeComprada,QuantidadeVendida,Lucro) :-
 	lucro(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,QuantidadeComprada,QuantidadeVendida,Lucro),
      	labeling([min,up],[PrecoVenda]), 
      	labeling([min,down],[PrecoCompra]),
      	labeling([min,up],[QuantidadeVendida]),
	!.

menorLucro(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,Quantidade,Lucro) :-
	menorLucro(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVenda,Quantidade,Quantidade,Lucro).

enum(tipo_operacao(O),corretora(C),PrecoCompra,PrecoVendaIni,PrecoVendaFim,QuantidadeComprada,QuantidadeVendida,PrecoVenda,Lucro) :- 
	PrecoVenda #>= PrecoVendaIni,
   	PrecoVenda #=< PrecoVendaFim,
   	balanco(tipo_operacao(O),corretora(C),PrecoCompra,
   	PrecoVenda,QuantidadeComprada,QuantidadeVendida,Lucro),
   	labeling([],[PrecoVenda,Lucro]).

compra(tipo_operacao(O),corretora(C),Montante,LotePadrao,PrecoCompra,QuantidadeComprada,Restante) :-
	X #>=1,
	QuantidadeComprada #= X * LotePadrao,
	A #= QuantidadeComprada * PrecoCompra,
	custo(tipo_operacao(O),A,corretora(C),CC),
	Restante #>= 0, 
	Restante #= Montante - A - CC,
	labeling([max,down],[PrecoCompra]),
        labeling([max,down],[QuantidadeComprada]).
	%labeling([max(X)],[X]).

venda(tipo_operacao(O),corretora(C),Preco,Quantidade,Disponivel) :-
	custo(tipo_operacao(O),corretora(C),Preco,Quantidade,Custo),
	Disponivel #= Preco * Quantidade - Custo.

minStopLoss(tipo_operacao(O),corretora(C),LotePadrao,PrecoCompra,Quantidade,MinStopLoss) :-
	compra(tipo_operacao(final),corretora(agora),Inicial,LotePadrao,PrecoCompra,Quantidade,0),
	%write('Inicial='),writeln(Inicial),
	Final #>= Inicial,
	Preco #> 0,
	Preco #< PrecoCompra,
	venda(tipo_operacao(O),corretora(C),PrecoCompra,Quantidade,Disponivel),
	compra(tipo_operacao(O),corretora(C),Disponivel,LotePadrao,Preco,QuantidadeComprada,Restante),
	venda(tipo_operacao(O),corretora(C),PrecoCompra,QuantidadeComprada,Disp),
	Final #= Disp + Restante,
	%write('Final='),writeln(Final),
	MinStopLoss #= Preco,!.

enum(tipo_operacao(O),corretora(C),PC,PVI,PVF,QC,QV) :- 
	bagof([PV,Lucro],enum(tipo_operacao(O),corretora(C),PC,PVI,PVF,QC,QV,PV,Lucro),BAG),write(BAG).


%%NAO TESTADO
rebound(tipo_operacao(O),corretora(C),Pa,Pb,Pc,Montante,Lucro,LotePadrao,Qc) :- 
	compra(tipo_operacao(O),corretora(C),Montante,LotePadrao,Pa,Qa,Ra),
	Pa #>0,
	Pb #>0,
	Pc #>0,
	Pb #=< Pa,
	Pc #=< Pb,
	Lucro #>=0,
	T1 #>=0,
	balanco(tipo_operacao(O),corretora(C),Pa,Pb,Qa,Qa,Bb),
	T1 #= Montante + Bb,
	compra(tipo_operacao(O),corretora(C),T1,LotePadrao,Pc,Qc,Rc),
	%writeln([T1,Lucro,Pa,Pb,Pc,Bb,Qc,Rc,Ra,Montante,Ba]),
	balanco(tipo_operacao(O),corretora(C),Pc,Pa,Qc,Qc,Ba),
	%writeln([T1,Lucro,Pa,Pb,Pc,Bb,Qc,Rc,Ra,Montante,Ba]),
	Lucro #= T1 + Ba - Montante.

%NAO TESTADO
minStopLoss(tipo_operacao(O),corretora(C),Pa,Pc,Montante,Lucro,LotePadrao,Qc) :-
	rebound(tipo_operacao(O),corretora(C),Pa,Pa,Pc,Montante,Lucro,LotePadrao,Qc),
	labeling([max(Pc),max(Qc)],[Pc,Lucro,Qc]).
	%labeling([min,up],[Pb]),!. 



